import imaplib
import email
import re
import time
import os
from bs4 import BeautifulSoup


class EmailChecker:
    def __init__(self, IMAP_HOST, EMAIL_ADDRESS, PASSWORD, FOLDER_SELECT):
        self.IMAP_HOST = IMAP_HOST
        self.EMAIL_ADDRESS = EMAIL_ADDRESS
        self.PASSWORD = PASSWORD
        self.FOLDER_SELECT = FOLDER_SELECT
        self.getSession()

    def getSession(self):
        imaplib.Commands['ID'] = ('AUTH')
        self.session = imaplib.IMAP4_SSL(port='993', host=self.IMAP_HOST)
        self.session.login(self.EMAIL_ADDRESS, self.PASSWORD)
        args = (
            "name",
            self.EMAIL_ADDRESS.split('@')[0],
            "contact",
            self.EMAIL_ADDRESS,
            "version", "1.0.0",
            "vendor",
            "myclient"
        )
        typ, dat = self.session._simple_command(
            'ID', '("' + '" "'.join(args) + '")')
        print(self.session._untagged_response(typ, dat, 'ID'))
        # 邮箱中的文件夹，默认为'INBOX'
        self.session.select(self.FOLDER_SELECT)
        # 搜索匹配的邮件，第一个参数是字符集，None默认就是ASCII编码，第二个参数是查询条件，这里的ALL就是查找全部
        typ, data = self.session.search(None, "ALL")
        #typ,data = self.session.sort('DATE','UTF-8', "ALL")
        # 邮件列表,使用空格分割得到邮件索引
        self.msgIndexs = data[0].split()
        # 最新邮件，第0封邮件为最早的一封邮件
        return self.session, self.msgIndexs

    def getContent(self, msgIndex):  # self.msgIndexs[id_]
        content = dict()
        typ, data = self.session.fetch(msgIndex, '(RFC822)')
        # 转化为email.message对象
        msg = email.message_from_bytes(data[0][1])

        From = msg.get("From")
        reobj = re.search("<(.*)@(.*)>", From, flags=0)
        From = reobj.group(1)+"@"+reobj.group(2)
        content["From"] = From

        Received = msg.get("Received")
        reobj = re.search(", (.*)(\d\d:\d\d:\d\d)", Received, flags=0)
        date = reobj.group(1).strip()
        time_ = reobj.group(2).strip()
        print("{} {}".format(date, time_))
        datetime_ = time.strptime("{} {}".format(
            date, time_), '%d %b %Y %H:%M:%S')
        datetime = time.strftime("%Y-%m-%d-%H-%M-%S", datetime_)
        #content["Date"] = date
        #content["Time"] = time_
        content["DateTime"] = datetime

        Subject = msg.get("Subject")
        header = email.header.decode_header(Subject)[0]
        Subject = header[0].decode(header[1])
        content["Subject"] = Subject

        # text and attachment
        dir_attachment = os.path.join(
            'workshops', "{}_{}".format(datetime, From))
        content2 = self.getTextAttachment(msg, msgIndex, dir_attachment)
        content.update(content2)
        return content

    def getTextAttachment(self, msg, msgIndex, dir_attachment):
        os.makedirs(dir_attachment, exist_ok=True)
        msg_id = msgIndex.decode()
        print(msg_id)
        content = {"text": "", "link": ""}
        if msg.is_multipart():
            pl = msg.get_payload()
            for m in pl:
                content_ = self.getTextAttachment(m, msgIndex, dir_attachment)
                if 'text' in content_.keys():
                    content['text'] += '\n'+content_['text']
                if 'link' in content_.keys():
                    content['link'] += '\n'+content_['link']
                if 'path' in content_.keys():
                    content['path'] = content_['path']

        else:
            ctype = msg.get_content_type()
            if 'html' in ctype:
                # 注意decode参数，如果是True将解码base64/quoted-printable等格式编码内容，否则不解码
                html = str(msg.get_payload(decode=True),
                           msg.get('content-type').split('=')[1])
                # BeautifulSoup解析网页
                soup = BeautifulSoup(html, "lxml")
                divs = soup.select('body')
                text = []
                for d in divs:
                    # 提取所有文本内容
                    text.append(d.get_text(strip=True))
                text = '\n'.join(text)
                content['text'] = text

                reobj = re.search("<a href=\"(.*?)\"", html, flags=0)
                if reobj is not None:
                    content['link'] = reobj.group(1)
                    print('\t', content['link'])
                print('\t', text)
            elif "txt" in ctype or "text" in ctype:
                try:
                    text = msg.get_payload(decode=True).decode('utf-8')
                except:
                    text = msg.get_payload(decode=True).decode('gbk')
                content["text"] = text
                print('\t', text)
            elif "image" in ctype or "application" in ctype or "officedocument" in ctype:
                filename = msg.get_filename()
                file = email.header.decode_header(filename)[0]
                if file[1] is None:
                    filename = file[0]
                else:
                    filename = file[0].decode(file[1])
                filename = os.path.join(dir_attachment, filename)
                with open(filename, 'wb') as f:
                    f.write(msg.get_payload(decode=True))
                content["path"] = dir_attachment
                print(filename)
            else:
                print('\t', ctype)

        return content
